Atraskite sudėtingas, slinkimo krypčiai jautrias interneto animacijas. Šis vadovas nagrinėja, kaip nustatyti slinkimo kryptį naudojant modernų CSS ir minimalų JavaScript pagalbininką, siekiant sukurti našias, slinkimu valdomas vartotojo sąsajas.
CSS slinkimo krypties nustatymas: išsami analizė apie kryptį jaučiančias animacijas
Internetas nuolat evoliucionuoja. Daugelį metų animacijų, reaguojančių į vartotojo slinkimo poziciją, kūrimas buvo išskirtinė JavaScript sritis. Bibliotekos, tokios kaip GSAP, ir pasirinktinės „Intersection Observer“ sąrankos buvo pagrindiniai įrankiai, reikalaujantys iš kūrėjų rašyti sudėtingą, imperatyvų kodą, kuris veikė pagrindinėje gijoje. Nors šis metodas buvo galingas, jis dažnai turėjo įtakos našumui, keldamas riziką dėl strigimo ir ne tokios sklandžios vartotojo patirties.
Įženkite į naują interneto animacijos erą: CSS slinkimu valdomos animacijos. Ši novatoriška specifikacija leidžia kūrėjams susieti animacijos eigą tiesiogiai su konteinerio slinkimo pozicija, ir visa tai deklaratyviai aprašoma CSS. Tai perkelia sudėtingą animacijos logiką iš pagrindinės gijos, todėl gaunami itin sklandūs, labai našūs efektai, kuriuos anksčiau buvo sunku pasiekti.
Tačiau dažnai kyla vienas esminis klausimas: ar galime padaryti šias animacijas jautrias slinkimo krypčiai? Ar elementas gali animuotis vienaip, kai vartotojas slenka žemyn, ir kitaip, kai slenka aukštyn? Šis vadovas pateikia išsamų atsakymą, nagrinėdamas šiuolaikinio CSS galimybes, dabartinius apribojimus ir geriausios praktikos, pasauliniu mastu orientuotą sprendimą, skirtą kurti stulbinančias, kryptį jaučiančias vartotojo sąsajas.
Senasis pasaulis: slinkimo kryptis su JavaScript
Prieš pasineriant į modernų CSS metodą, naudinga suprasti tradicinį būdą. Daugiau nei dešimtmetį slinkimo krypties nustatymas buvo klasikinė JavaScript problema. Logika yra paprasta: klausytis slinkimo įvykio, palyginti dabartinę slinkimo poziciją su ankstesne ir nustatyti kryptį.
Tipinė JavaScript implementacija
Paprasta implementacija galėtų atrodyti maždaug taip:
// Store the last scroll position globally
let lastScrollY = window.scrollY;
window.addEventListener('scroll', () => {
const currentScrollY = window.scrollY;
if (currentScrollY > lastScrollY) {
// Scrolling down
document.body.setAttribute('data-scroll-direction', 'down');
} else {
// Scrolling up
document.body.setAttribute('data-scroll-direction', 'up');
}
// Update the last scroll position for the next event
lastScrollY = currentScrollY;
});
Šiame scenarijuje prijungiame įvykių klausytoją prie lango slinkimo įvykio. Klausytojo viduje tikriname, ar nauja vertikali slinkimo pozicija (`currentScrollY`) yra didesnė už paskutinę žinomą poziciją (`lastScrollY`). Jei taip, slenkame žemyn; kitu atveju, slenkame aukštyn. Tada dažnai nustatome duomenų atributą `
` elementui, kurį CSS vėliau gali naudoti kaip kabliuką, taikant skirtingus stilius ar animacijas.JavaScript metodo apribojimai
- Našumo pridėtinės išlaidos: `scroll` įvykis gali suveikti dešimtis kartų per sekundę. Sudėtingos logikos ar DOM manipuliacijų prijungimas tiesiogiai prie jo gali blokuoti pagrindinę giją, sukeldamas trūkčiojimą ir strigimą, ypač mažesnio galingumo įrenginiuose.
- Sudėtingumas: Nors pagrindinė logika yra paprasta, animacijos būsenų valdymas, „debouncing“ ar „throttling“ taikymas našumui ir užtikrinimas, kad viskas būtų išvalyta, gali gerokai padidinti jūsų kodo sudėtingumą.
- Atsakomybių atskyrimas: Animacijos logika susipina su programos logika JavaScript'e, ištrindama ribas tarp elgsenos ir pateikimo. Idealiu atveju, vizualinis stilius ir animacija turėtų būti aprašyti CSS.
Naujoji paradigma: CSS slinkimu valdomos animacijos
CSS slinkimu valdomų animacijų specifikacija iš esmės keičia mūsų požiūrį į slinkimu pagrįstas sąveikas. Ji suteikia deklaratyvų būdą valdyti CSS animacijos eigą, susiejant ją su slinkimo laiko juosta.
Dvi pagrindinės savybės, esančios šios naujos API centre, yra:
animation-timeline: Ši savybė priskiria pavadintą laiko juostą animacijai, efektyviai atskirdama ją nuo numatytosios dokumento laiko eigos.scroll-timeline-nameirscroll-timeline-axis: Šios savybės (taikomos slenkančiam elementui) sukuria ir pavadina slinkimo laiko juostą, į kurią vėliau gali kreiptis kiti elementai.
Neseniai atsirado galinga trumpoji forma, kuri labai supaprastina šį procesą, naudojant `scroll()` ir `view()` funkcijas tiesiogiai `animation-timeline` savybėje.
`scroll()` ir `view()` funkcijų supratimas
scroll(): slinkimo eigos laiko juosta
`scroll()` funkcija sukuria anoniminę laiko juostą, pagrįstą konteinerio (slinkiklio) slinkimo eiga. Su šia laiko juosta susieta animacija vyks nuo 0% iki 100%, kai slinkiklis judės nuo pradinės slinkimo pozicijos iki maksimalios.
Klasikinis pavyzdys yra skaitymo eigos juosta straipsnio viršuje:
/* CSS */
#progress-bar {
transform-origin: 0 50%;
animation: grow-progress linear;
animation-timeline: scroll(root block);
}
@keyframes grow-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
Šiame pavyzdyje `grow-progress` animacija yra tiesiogiai susieta su viso dokumento (`root`) slinkimo pozicija jo vertikalioje (`block`) ašyje. Nereikia jokio JavaScript, kad atnaujintumėte eigos juostos plotį.
view(): matomumo eigos laiko juosta
`view()` funkcija yra dar galingesnė. Ji sukuria laiko juostą, pagrįstą elemento matomumu slinkiklio matomumo srityje (viewport). Animacija vyksta, kai elementas įeina, kerta ir išeina iš matomumo srities.
Tai puikiai tinka išblukimo efektams, kai elementai atsiranda slenkant:
/* CSS */
.fade-in-element {
opacity: 0;
animation: fade-in linear forwards;
animation-timeline: view();
animation-range-start: entry 0%;
animation-range-end: entry 40%;
}
@keyframes fade-in {
to { opacity: 1; }
}
Čia `fade-in` animacija prasideda, kai elementas pradeda patekti į matomumo sritį (`entry 0%`), ir baigiasi, kai jis yra 40% matomumo srities viduje (`entry 40%`). `forwards` užpildymo režimas užtikrina, kad elementas liks matomas pasibaigus animacijai.
Pagrindinis iššūkis: kur yra slinkimo kryptis gryname CSS?
Su šiuo galingu nauju kontekstu grįžtame prie pradinio klausimo: kaip galime nustatyti slinkimo kryptį?
Trumpas ir tiesus atsakymas: pagal dabartinę specifikaciją, nėra jokios įgimtos CSS savybės, funkcijos ar pseudo-klasės, kuri tiesiogiai nustatytų slinkimo kryptį.
Tai gali atrodyti kaip didelis trūkumas, bet tai kyla iš deklaratyvios CSS prigimties. CSS yra sukurtas apibūdinti dokumento būseną, o ne sekti būsenos pokyčius laikui bėgant. Krypties nustatymui reikia žinoti *ankstesnę* būseną (paskutinę slinkimo poziciją) ir palyginti ją su *dabartine* būsena. Šio tipo būsenos logika yra tai, kam iš esmės sukurtas JavaScript.
Hipotetinė `scrolling-up` pseudo-klasė ar `scroll-direction()` funkcija reikalautų, kad CSS variklis saugotų kiekvieno elemento slinkimo pozicijų istoriją, o tai pridėtų didelį sudėtingumą ir galimą našumo sumažėjimą, prieštaraujantį pagrindiniams CSS dizaino principams.
Taigi, jei grynas CSS to padaryti negali, ar grįžtame į pradinį tašką? Visai ne. Dabar galime taikyti labai optimizuotą, modernų hibridinį požiūrį, kuris sujungia geriausias abiejų pasaulių savybes.
Pragmatiškas ir našus sprendimas: minimalus JS pagalbininkas
Efektyviausias ir plačiausiai pripažintas sprendimas yra naudoti mažytį, labai našų JavaScript fragmentą vienai užduočiai, kurioje jis yra nepralenkiamas – būsenos nustatymui – ir palikti visą sunkųjį animacijos darbą CSS.
Naudosime tą patį loginį principą kaip ir senajame JavaScript metode, bet mūsų tikslas kitoks. Mes neleidžiame animacijų JavaScript'e. Mes tiesiog perjunginėjame atributą, kurį CSS naudos kaip kabliuką.
1 žingsnis: JavaScript būsenos detektorius
Sukurkite nedidelį, efektyvų scenarijų, kuris sektų slinkimo kryptį ir atnaujintų `data-` atributą `
` elemente arba atitinkamame slenkančiame konteineryje.
let lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;
// A function that's optimized to run on each scroll
const storeScroll = () => {
const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop;
if (currentScrollTop > lastScrollTop) {
// Downscroll
document.body.setAttribute('data-scroll-direction', 'down');
} else {
// Upscroll
document.body.setAttribute('data-scroll-direction', 'up');
}
lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop; // For Mobile or negative scrolling
}
// Listen for scroll events
window.addEventListener('scroll', storeScroll, { passive: true });
// Initial call to set direction on page load
storeScroll();
Pagrindiniai patobulinimai šiame moderniame scenarijuje:
{ passive: true }: Mes nurodome naršyklei, kad mūsų slinkimo klausytojas nekviess `preventDefault()`. Tai yra esminis našumo optimizavimas, nes leidžia naršyklei nedelsiant apdoroti slinkimą, nelaukiant, kol mūsų scenarijus baigs vykdymą, taip išvengiant slinkimo strigimo.data-attribute: `data-scroll-direction` naudojimas yra švarus, semantinis būdas saugoti būseną DOM'e, netrukdant klasių pavadinimams ar ID.- Minimali logika: Scenarijus daro vieną ir tik vieną dalyką: palygina du skaičius ir nustato atributą. Visa animacijos logika yra perduota CSS.
2 žingsnis: kryptį jaučiančios CSS animacijos
Dabar savo CSS galime naudoti atributų selektorius, kad taikytume skirtingus stilius ar animacijas, priklausomai nuo slinkimo krypties.
Sukurkime įprastą vartotojo sąsajos šabloną: antraštę, kuri pasislepia slenkant žemyn, kad maksimaliai išnaudotų ekrano plotą, bet vėl atsiranda vos tik pradedant slinkti aukštyn, suteikiant greitą prieigą prie naršymo.
HTML struktūra
<body>
<header class="main-header">
<h1>My Website</h1>
<nav>...</nav>
</header>
<main>
<!-- A lot of content to make the page scrollable -->
</main>
</body>
CSS magija
.main-header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background-color: #ffffff;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
transform: translateY(0%);
transition: transform 0.4s ease-in-out;
}
/* When scrolling down, hide the header */
body[data-scroll-direction="down"] .main-header {
transform: translateY(-100%);
}
/* When scrolling up, show the header */
body[data-scroll-direction="up"] .main-header {
transform: translateY(0%);
}
/* Optional: Keep header visible at the very top of the page */
/* This requires a little more JS to add a class when scrollTop is 0 */
body.at-top .main-header {
transform: translateY(0%);
}
Šiame pavyzdyje pasiekėme sudėtingą, kryptį jaučiančią animaciją beveik be JavaScript. CSS yra švarus, deklaratyvus ir lengvai suprantamas. Naršyklės kompozitorius gali optimizuoti `transform` savybę, užtikrindamas, kad animacija veiktų sklandžiai, ne pagrindinėje gijoje.
Šis hibridinis požiūris yra dabartinė pasaulinė geriausia praktika. Jis švariai atskiria atsakomybes: JavaScript tvarko būseną, o CSS – pateikimą. Rezultatas yra kodas, kuris yra našus, lengvai prižiūrimas ir patogus tarptautinėms komandoms bendradarbiauti.
Geriausios praktikos pasaulinei auditorijai
Įgyvendinant slinkimu valdomas animacijas, ypač tas, kurios jautrios krypčiai, labai svarbu atsižvelgti į įvairius vartotojus ir įrenginius visame pasaulyje.
1. Teikite pirmenybę prieinamumui su `prefers-reduced-motion`
Kai kurie vartotojai patiria judesio ligą ar vestibiuliarinius sutrikimus, o didelio masto animacijos gali būti klaidinančios ar net žalingos. Visada gerbkite vartotojo sistemos lygio pageidavimą dėl sumažinto judesio.
@media (prefers-reduced-motion: reduce) {
.main-header {
/* Disable the transition for users who prefer less motion */
transition: none;
}
/* Or you can opt for a subtle fade instead of a slide */
body[data-scroll-direction="down"] .main-header {
opacity: 0;
transition: opacity 0.4s ease;
}
body[data-scroll-direction="up"] .main-header {
opacity: 1;
transition: opacity 0.4s ease;
}
}
2. Užtikrinkite naršyklių suderinamumą ir progresyvų tobulinimą
CSS slinkimu valdomos animacijos yra nauja technologija. Nors palaikymas sparčiai auga visose pagrindinėse nuolat atnaujinamose naršyklėse, jis dar nėra universalus. Naudokite `@supports` taisyklę, kad užtikrintumėte, jog jūsų animacijos bus taikomos tik tose naršyklėse, kurios jas supranta, suteikiant stabilią, atsarginę patirtį kitoms.
/* Default styles for all browsers */
.fade-in-on-scroll {
opacity: 1; /* Visible by default if animations aren't supported */
}
/* Apply scroll-driven animations only if the browser supports them */
@supports (animation-timeline: view()) {
.fade-in-on-scroll {
opacity: 0;
animation: fade-in linear forwards;
animation-timeline: view();
animation-range: entry 0% cover 40%;
}
}
@keyframes fade-in {
to { opacity: 1; }
}
3. Pagalvokite apie našumą pasauliniu mastu
Nors CSS animacijos yra daug našesnės už JavaScript pagrįstas, kiekvienas sprendimas turi įtakos, ypač vartotojams su žemos klasės įrenginiais ar lėtu interneto ryšiu.
- Animuokite „pigias“ savybes: Kai tik įmanoma, stenkitės animuoti `transform` ir `opacity`. Šias savybes gali apdoroti naršyklės kompozitorius, o tai reiškia, kad jos nesukelia brangių išdėstymo perskaičiavimų ar perpiešimų. Venkite animuoti tokias savybes kaip `width`, `height`, `margin` ar `padding` slinkimo metu.
- Išlaikykite JavaScript „liesą“: Mūsų krypties nustatymo scenarijus jau yra mažytis, bet visada būkite atidūs pridėdami daugiau logikos į slinkimo įvykio klausytoją. Kiekviena milisekundė yra svarbi.
- Venkite perteklinės animacijos: Tai, kad galite animuoti viską slinkimo metu, nereiškia, kad turėtumėte. Naudokite slinkimu valdomus efektus tikslingai, siekdami pagerinti vartotojo patirtį, nukreipti dėmesį ir suteikti grįžtamąjį ryšį, o ne tik dėl dekoracijos. Subtilumas dažnai yra efektyvesnis nei dramatiškas, visą ekraną užpildantis judesys.
Išvada: ateitis yra hibridinė
Interneto animacijų pasaulis žengė milžinišką žingsnį į priekį su CSS slinkimu valdomų animacijų įdiegimu. Dabar galime kurti neįtikėtinai turtingas, našias ir interaktyvias patirtis su dalimi anksčiau reikalingo kodo ir sudėtingumo.
Nors grynas CSS dar negali nustatyti vartotojo slinkimo krypties, tai nėra specifikacijos nesėkmė. Tai atspindi brandų ir gerai apibrėžtą atsakomybių atskyrimą. Optimalus sprendimas – galingas CSS deklaratyvios animacijos variklio ir minimalios JavaScript būsenos sekimo galimybės derinys – atspindi modernaus front-end kūrimo viršūnę.
Pasirinkę šį hibridinį požiūrį, galite:
- Kurti žaibiškai greitas vartotojo sąsajas: Perkelkite animacijos darbą iš pagrindinės gijos, kad užtikrintumėte sklandesnę vartotojo patirtį.
- Rašyti švaresnį kodą: Laikykite pateikimo logiką CSS, o elgsenos logiką – JavaScript.
- Kurti sudėtingas sąveikas: Lengvai kurkite kryptį jaučiančius komponentus, tokius kaip automatiškai pasislepiančios antraštės, interaktyvūs pasakojimo elementai ir dar daugiau.
Pradėdami integruoti šias technikas į savo darbą, prisiminkite pasaulines geriausias prieinamumo, našumo ir progresyvaus tobulinimo praktikas. Taip darydami, kursite interneto patirtis, kurios bus ne tik gražios ir įtraukiančios, bet ir įtraukios bei atsparios visame pasaulyje.